#include "GLFWApp.h"
#include "shapes3d.h"
#include "OpenGLHelpers.h"
#include "OpenGLDebug.h"

class GameManager : public GLFWApp
{

private:


public:
	GameManager() : GLFWApp()
	{
		init();
		mainloop();
	}
	
	void init() 
	{
		glMatrixMode(GL_PROJECTION);
		glusPerspective(60., xres/double(yres), .05, 100.);
		glMatrixMode(GL_MODELVIEW);

		glEnable (GL_DEPTH_TEST);
		glEnable (GL_LIGHTING);
		glEnable (GL_LIGHT0);

		glDisable(GL_CULL_FACE);

		checkGLErrors();

	}
	
	void light() 
	{	
		static GLfloat whiteSpecularLight[] = {1.0, 1.0, 1.0}; //set the light specular to white
		static GLfloat blackAmbientLight[] = {0.0, 0.0, 0.0}; //set the light ambient to black
		static GLfloat whiteDiffuseLight[] = {1.0, 1.0, 1.0}; //set the diffuse light to white

		glLightfv(GL_LIGHT0, GL_SPECULAR, whiteSpecularLight);
		glLightfv(GL_LIGHT0, GL_AMBIENT, blackAmbientLight);
		glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteDiffuseLight);
	}
	
	void render()
	{
		int teapotRez = Input::mouseX() / float(xres) * 30;

		char str[200];
		sprintf_s( str, 200,  "Press S E D to toggle spec, emiss, diff light, teapot rez: %i", teapotRez);
		glfwSetWindowTitle( str );

		GLfloat angle = (float) glfwGetTime() * 45.0f;

		glClearColor (0.0,0.0,0.0,1.0);
		glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glLoadIdentity(); 
		
		glTranslatef(0,0,-5);
		glRotatef(angle,1,1,1);

		light();
		
		// Scale teapot inside out for Nvidia cards. OpenGL bezier surf eval is fubar? Different on ati and nvidia
		//glScalef(-1,-1,-1);
		//Shapes3D::FastTeapot( teapotRez, 2);
		Shapes3D::DrawTorus(0.5, 1.0);
		//Shapes3D::DrawCylinder(1,3,16,true);

		glfwSwapBuffers();
		
	}

	void update()
	{
		static bool diffuse = false;
		static bool emissive = false;
		static bool specular = false;
		static bool wireframe = false;

		static GLfloat redDiffuseMaterial[] = {1.0, 0.0, 0.0}; //set the material to red
		static GLfloat whiteSpecularMaterial[] = {1.0, 1.0, 1.0}; //set  the material to white
		static GLfloat greenEmissiveMaterial[] = {0.0, 1.0, 0.0}; //set the material to green

		static GLfloat blankMaterial[] = {0.0, 0.0, 0.0}; //set the diffuse light to white
		static GLfloat mShininess[] = {64}; //set the shininess of the material

		if ( Input::keyHit('W') ) 
		{
			wireframe = !wireframe;

			if( wireframe ) glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
			if( !wireframe ) glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
		}

		if ( Input::keyHit('S') ) 
		{
			if (specular==false)
			{
				specular = true;
				glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, whiteSpecularMaterial);
				glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mShininess);
			}
			else if (specular==true)
			{
				specular = false;
				glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blankMaterial);
				glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, blankMaterial);
			}
		}
		
		if ( Input::keyHit('D') ) 
		{
			if (diffuse==false)
			{
				diffuse = true;
				glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, redDiffuseMaterial);
			}
			else if (diffuse==true)
			{
				diffuse = false;
				glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, blankMaterial);
			}
		}
		
		if ( Input::keyHit('E') ) 
		{
			if (emissive==false)
			{
				emissive = true;
				glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, greenEmissiveMaterial);
			}
			else if (emissive==true)
			{
				emissive = false;
				glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, blankMaterial);
			}
		}
	}



};